package com.lyj.thread.syncutil;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * 共享锁
 * 线程计数器：CountDownLatch是一个同步工具类，用来协调多个线程之间的同步，用来作为线程间的通信而不是互斥作用。
 * 某一线程在开始运行前等待n个线程执行完毕
 * 将CountDownLatch的计数器初始化为：new CountDownLatch(n)，每当一个任务线程执行完毕，计数器减一 countdownlatch.countDown()，
 * 当计数器的值变为0时，在CountDownLatch上await()的线程就会被唤醒。
 * 一个典型应用场景就是启动一个服务时，主线程需要等待多个组件加载完毕，之后再继续执行
 */
public class CountDownLatchDemo {

    // 构造一个指定线程数量的计数器
    private static CountDownLatch countDownLatch = new CountDownLatch(5);

    public static void main(String[] args) throws InterruptedException {

        for (int i =0 ; i<5 ; i++) {
            new Thread(new CountDownLatchTask(countDownLatch , i)).start();
        }
        countDownLatch.await();
        // 主线程调用方法countDownLatch.await()，只有当所有的子线程全部执行完毕，才能继续执行调用countDownLatch.await()的线程
        System.out.println("子线程执行完毕，" + Thread.currentThread().getName() +"，开始执行");
    }
}

class CountDownLatchTask implements Runnable{
    CountDownLatch count;
    int i ;

    public CountDownLatchTask(CountDownLatch count, int i) {
        this.count = count;
        this.i = i;
    }

    @Override
    public void run() {
        try{
            TimeUnit.MILLISECONDS.sleep(2000);
            // 子任务异常，也算作执行完成
//            if (i == 1) {
//                throw new RuntimeException(Thread.currentThread().getName() + "，执行异常");
//            }
            System.out.println(Thread.currentThread().getName() + "，执行完毕");
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            count.countDown();
        }

    }
}